home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / PostScriptFiles / BitmapProcs.ps next >
Encoding:
Text File  |  2000-09-28  |  30.8 KB  |  1,013 lines  |  [TEXT/MPS ]

  1. %
  2. %    File:        BitmapProcs.ps
  3. %
  4. %    Contains:    This file contains Procedures needed to render bitmap shapes and using colorsets
  5. %
  6. %    Version:    Technology:    Quickdraw GX 1.1.x.
  7. %
  8. %    Copyright:    © 1991-7 by Apple Computer, Inc., all rights reserved.
  9. %
  10. %
  11.  
  12. %
  13. %
  14. %            Procedure:    ReadRaster
  15. %            procedure is passed as the proc to image.  It depends on the value of RstrRead
  16. %                    which is set by the various bitmap procedures.
  17. %
  18. /ReadRaster { currentfile pixString RstrRead pop } Bdef
  19.  
  20. %
  21. %    Define some values in our dictionary that procs will use for drawing bitmaps.
  22. %
  23. /pixString null def
  24. /MaxSampleInt 0 def
  25. /OldGrayTransfer null def
  26. /OldBlackTransfer null def
  27. /OldRedTransfer null def
  28. /OldGreenTransfer null def
  29. /OldBlueTransfer null def
  30. /OldCyanTransfer null def
  31. /OldMagentaTransfer null def
  32. /OldYellowTransfer null def
  33.  
  34.  
  35. %<FF>
  36. %            Procedure:  DoBitmap
  37. %            Procedure renders a bimtap shape.
  38. %
  39. %                nPlanes width height bits/sample x y hex rowBytes DoBitmap -
  40. %
  41. %                    nPlanes:                #color planes
  42. %                    width:                    The width in pixels of the bitmap.
  43. %                    height:                    The height in pixels of the bitmap.
  44. %                    bits/sample:        pixelSize value.
  45. %                    x, y:                        Position of the bitmap in user space.
  46. %                    hex:                        Boolean, true if data will be hex.
  47. %                    rowBytes:                #bytes required for one scanline.
  48. %
  49.  
  50. /DoBitmap { save            % Bitmaps use a lot of memory.
  51.  
  52.     9 1 roll                        % Move the savelevel behind the parameters.
  53.     
  54.     /pixString exch string store                % Allocate a string for the scanline.
  55.     /RstrRead exch                                            % Define the read operator based on hex value.
  56.         {/readhexstring}
  57.         {/readstring}
  58.     ifelse
  59.     load def
  60.     
  61.     1 0 0 1                                                                                % Make mapping [1 0 0 1 -x -y]
  62.     6 -2 roll neg exch neg exch                                     % for the image operator's matrix.
  63.     ScratchMatrix astore                                                    % so bitmap positions properly.
  64.  
  65.     
  66.     /ReadRaster load 
  67.     % Stack is now:   nPlanes width height bits/sample matrix dataInProc
  68.     
  69.     6 -1 roll dup 1 gt {                % If #planes > 1 then
  70.         false exch                                %        multiple sources = false.
  71.         GXColorImage                            %        do a color image operation.
  72.     } {                                                    % Else
  73.         pop                                                %        Get rid of #components.
  74.         image                                            %        do a standard image operation.
  75.     } ifelse
  76.  
  77. restore } Bdef
  78.  
  79.  
  80. %<FF>
  81. %                Procedure DoImageMask:
  82. %                Procedure renders a one bit bitmap using the ImageMask operator.
  83. %
  84. %                width height x y hex rowBytes DoImageMask -
  85. %
  86. %                    width:                    The width in pixels of the bitmap.
  87. %                    height:                    The height in pixels of the bitmap.
  88. %                    x, y:                        Position of the bitmap in user space.
  89. %                    hex:                        Boolean, true if data will be hex.
  90. %                    rowBytes:                #bytes required for one scanline.
  91. %
  92. /DoImageMask { save
  93.  
  94.     1 index type /arraytype eq {                % If the top parameter is an array, then this its additional mapping
  95.                                                                             %        from rasterizing shape, concat with CTM and set orMode to 1.
  96.         exch concat                                                %        It will be restored by "restore" at end of this routine.
  97.         1 SetOrMode                                                %        So will this.  Rasterized shapes are evil and only added to make Japanese work.
  98.  
  99.         EnsureDeviceResolution                        %        We mean to be doing device res here, make sure we are
  100.                                                                             %        So we hit the fast blitter
  101.     } if
  102.  
  103.     7 1 roll                                                        % Move save level behind parameters.
  104.  
  105.     /pixString exch string store                % Allocate a string for the scanline.
  106.     /RstrRead exch                                            % Define the read operator based on hex value.
  107.         {/readhexstring}
  108.         {/readstring}
  109.     ifelse
  110.     load def
  111.                                                                                                 % Stack is: width height x y
  112.     1 0 0 1                                                                                % Make mapping [1 0 0 1 -x -y]
  113.     6 -2 roll neg exch neg exch                                     % for the image operator's matrix.
  114.     ScratchMatrix astore                                                    % so bitmap positions properly.
  115.     
  116.     ImageMaskSense exch                                                        % Put boolean for which bits to paint on stack.
  117.     /ReadRaster load 
  118.     % Stack is now:   nPlanes width height sense matrix dataInProc
  119.     
  120.     gsave ImageMaskColor CurrColorSet SetIndexedColor
  121.     imagemask    
  122.     grestore
  123.  
  124. restore } Bdef
  125.  
  126.  
  127. %<FF>
  128. %
  129. %        Procedure:        MakeBitmapStrings
  130. %        Procedure makes an array of strings containg all of the data for a bitmap shape.  Thus
  131. %         we can have bitmap procedures.  The data is in an array of strings becuase of the 64k
  132. %         string limit in PostScript
  133. %
  134. %
  135. %            hex dataSize MakeBitmapStrings stringArray
  136. %
  137. %                    hex:                        Boolean, true if data will be hex.
  138. %                    dataSize:                the total number of bytes for all of the bitmap data.
  139. %
  140. %                    stringArray:        Array of strings, left on stack.
  141. %
  142. /MakeBitmapStrings {
  143.  
  144.     % Allocate the array of strings:
  145.     
  146.     
  147.     /@1 Xstore                                                            % Put the size into @1
  148.     
  149.     [                                                                                % start an array 
  150.     
  151.         @1 -65535 0 {                                                    % Make strings in up to 64k chunks.
  152.         
  153.             dup 65535 gt {                                            % More than 64k left?
  154.             
  155.                 pop 65535 string                                    %        Yes, make a 64k string
  156.                 
  157.             } {                                                                    %    Else
  158.             
  159.                 string                                                        %     Just make a string for the remainder which is on stack.
  160.                 
  161.             } ifelse
  162.         
  163.         } for
  164.     
  165.     ]                                                                             % Leave array on stack.
  166.     
  167.     %
  168.     %    Stack is:  hex array
  169.     %
  170.     
  171.     exch
  172.     
  173.     /RstrRead exch                                            % Define the read operator based on hex value.
  174.         {/readhexstring}
  175.         {/readstring}
  176.     ifelse
  177.     load def
  178.  
  179.     dup                % Leave a copy of the string array on the stack for the function result.
  180.  
  181.     %
  182.     % Now read the data into the strings
  183.     %
  184.  
  185.     {                    % array of strings is on the stack.
  186.     
  187.         currentfile exch RstrRead pop pop
  188.     
  189.     } forall
  190.  
  191. } Bdef
  192.  
  193.  
  194. %<FF>
  195. %
  196. %        StringDataIn:            Procedure that can be passed to an image operator to get the data from
  197. %                                                        the string array.  index must be started at zero.
  198. %
  199. %                StringArray index StringDataIn StringArray index+1 dataString
  200. %                    Reads the string from the specified index in the string array.
  201. %                    Leaves the string on the stack and increments the index, left on stack.
  202. %
  203. /StringDataIn {
  204.  
  205.     2 copy get exch 1 add exch
  206.  
  207. } Bdef
  208.  
  209.  
  210. %<FF>
  211. %        Procedure:        DrawBitmapString
  212. %
  213. %        Procedure is much like DoBitmap, only it draws the bitmap that is contained in the
  214. %            Array of strings in the shape dict rather than reading the bitmap data from the current file
  215. %            The shape dictionary with the entry "BitmapStrings" will be assumed to be on the dictionary stack.
  216. %
  217. %            nPlanes width height bits/sample x y DrawBitmapString -
  218. %
  219. %            nPlanes:                        #color planes
  220. %            width:                            The width in pixels of the bitmap.
  221. %            height:                            The height in pixels of the bitmap.
  222. %            bits/sample:                pixelSize value.
  223. %            x, y:                                Position of the bitmap in user space.
  224. %
  225. /DrawBitmapString {
  226.  
  227.     1 0 0 1                                                                                % Make mapping [1 0 0 1 -x -y]
  228.     6 -2 roll neg exch neg exch                                     % for the image operator's matrix.
  229.     ScratchMatrix astore                                                    % so bitmap positions properly.
  230.  
  231.     /StringDataIn load                                                        % DataIn proc.
  232.                                                                                                 
  233.     % Stack is now: nPlanes width height bits/sample matrix dataInProc
  234.     
  235.     BitmapStrings 0                                                                % Put initial array index on stack.
  236.     8 2 roll                                                                            % Put it behind everything except array o'strings.
  237.     
  238.     % Stack is now: bitStringArray index nPlanes width height bits/sample matrix dataInProc
  239.     
  240.     6 -1 roll dup 1 gt {                % If #planes > 1 then
  241.         false exch                                %        multiple sources = false.
  242.         GXColorImage                            %        do a color image operation.
  243.     } {                                                    % Else
  244.         pop                                                %        Get rid of #components.
  245.         image                                            %        do a standard image operation.
  246.     } ifelse
  247.  
  248.     pop pop                                    % Get rid of last index and copy of string array.    
  249.  
  250. } Bdef
  251.  
  252.  
  253. %<FF>
  254. %        Procedure:        Draw1bitBitmapString
  255. %
  256. %        Procedure is much like Do1bitBitmap, only it draws the bitmap that is contained in the
  257. %            Array of strings in the shape dictionary rather than reading the bitmap data from the current file.
  258. %            The shape dictionary with the entry "BitmapStrings", "colorSet" and "shapeType" will be assumed to be on the dictionary stack.
  259. %            Additionally, it will be painted in or-mode, using the current color.  This is used for bitmap
  260. %            patterns and the pattern filling code handles the background color for copy-mode.
  261. %
  262. %            width height x y Draw1bitmapString -
  263. %
  264. %            width:                            The width in pixels of the bitmap.
  265. %            height:                            The height in pixels of the bitmap.
  266. %            x, y:                                Position of the bitmap in user space.
  267. %
  268. /Draw1bitBitmapString {
  269.     
  270.     %
  271.     % if the shape type is /i "image" as opposed too "b" for 1 bit bitmap then paint in background color
  272.     %        for copymode by drawing rectangle to to simulate painting of zero-bits.
  273.     %
  274.     %        Level-1 MakePatternDict will change shape type from /b to /i when lattice is not same size as bitmap.
  275.     %            This prevents PatternFill from doing a fill of the shape in the background color for copy mode.
  276.     %            And, unfortunately, from using the font cache for the bitmap shape.
  277.     %
  278.     shapeType /i eq CurrOrMode 0 eq and {            % For image shape type in copy, use Indexed bitmap proc.
  279.     
  280.         1                                                    % One bit per sample
  281.         3 1 roll                                    % Stack is: width height bits/sample x y
  282.         DrawIndexedBitmapStrings    % Invoke the procedure.
  283.         
  284.     } {
  285.  
  286.         1 0 0 1                                                                                % Make mapping [1 0 0 1 -x -y]
  287.         6 -2 roll neg exch neg exch                                     % for the image operator's matrix.
  288.         ScratchMatrix astore                                                    % so bitmap positions properly.
  289.             
  290.         ImageMaskSense exch                                                        % Paint the one or zero bits based on orMode.
  291.     
  292.         /StringDataIn load                                                        % DataIn proc.
  293.                                                                                                     
  294.         % Stack is now: width height true matrix dataInProc
  295.         
  296.         BitmapStrings 0                                                                % Put strings and initial array index on stack.
  297.         7 2 roll                                                                            % Put it behind everything except array o'strings.
  298.         
  299.         % Stack is now: bitStringArray index width height matrix sense dataInProc
  300.         
  301.         imagemask                                                                            % Draw the bitmap.
  302.         
  303.         pop pop                                    % Get rid of last index and copy of string array.    
  304.         
  305.     } ifelse
  306.     
  307. } Bdef
  308.  
  309.  
  310.  
  311. %<FF>
  312. % Determinte wheither or not to define the following procedure.
  313. %
  314. languagelevel 1 eq {                                        % Only define for level-1
  315.     statusdict /processcolors known {            %        If the processcolors entry is available
  316.         statusdict /processcolors                        %            execute the processcolors operator.
  317.         get exec 4 ne                                                %            boolean left on stack for de-defining the procedure.  set to true if processcolors was 4.
  318.     } {                                                                        %     else
  319.         true                                                                %         processcolors wasn't defined, leave true, telling us to de-define the procedure.
  320.     }ifelse
  321. } {                                                                            % Else
  322.     true                                                                    %     level-2, leave true, telling us to de-define the procedure
  323. } ifelse
  324.  
  325. % Stack has boolean: whether or not to de-define the following procedure.
  326.  
  327. {save true} {false} ifelse                % If we are told to de-define, then put a save on the stack followed by a true, else leave false. 
  328.                                                                     %        stack is either: <saveobj true>, or <false>
  329.  
  330.     %
  331.     %        RGBtoCMYKColorSetParams
  332.     %
  333.     %            This routine converts an RGB color set to a CMYK colorset, if the printer
  334.     %                is a CMYK printer.  This is because on a CMYK printer we are using the 
  335.     %                transfer functions to simulate indexed colorsets when drawing images and
  336.     %                in the case of RGB, colroimage will muck with our image data using Undercolor removal
  337.     %                functions and black generation and this happens before our colorset transfer functions
  338.     %                or invoked.
  339.     %
  340.     %            So, if the input colorspace is RGB then we will return a CMYK one.
  341.     %
  342.     %            cmpArray1… cmpArrayN colorSpace NRGBtoCMYKColorSetParams cmpArray1… cmpArrayN colorSpace N
  343.     %                cmpArray1 through N:            Array of component values for each component.
  344.     %                colorSpace:                                If applicable, a Level-2 ColorSpace, otherwise nil
  345.     %                N:                                                Number of components, 1 implies gray, 3 implies rgb, 4 cmyk unless there is a colorspace
  346.     %                                                                        in which case it will be assumed that the number of components makes sense for setcolor
  347.     %
  348.     
  349.     
  350.     /RGBtoCMYKColorSetParams {
  351.     
  352.         dup 3 eq {                    % Only do anything if we are an RGB colorspace
  353.             
  354.             5 -3 roll                                        % Stack is: colorSpace N redArray greenArray blueArray
  355.             dup length array                        % Stack is: colorSpace N redArray greenArray blueArray mewArray
  356.             
  357.             0 1 2 index length 1 sub        % Stack is: colorSpace N redArray greenArray blueArray mewArray 0 1 length-1
  358.             {                                                        % Loop on all components., i is pushed
  359.     
  360.                 % Stack is:    colorSpace N redArray greenArray blueArray mewArray i
  361.                                                                             
  362.                 dup 5 index exch get exch            % Stack is: colorSpace N redArray greenArray blueArray mewArray red[i] i
  363.                 dup 5 index exch get exch            % Stack is: colorSpace N redArray greenArray blueArray mewArray red[i] green[i] i
  364.                 dup 5 index exch get exch         % Stack is: colorSpace N redArray greenArray blueArray mewArray red[i] green[i] blue[i] i
  365.                 
  366.                 % Now apply the black generation and undercolor removal to the RGB.
  367.                 %  and stuff the values back into the component arrays.
  368.                 
  369.                 4 1 roll                                            % Stack is: colorSpace N redArray greenArray blueArray newArray i red[i] green[i] blue[i]
  370.                 setrgbcolor currentcmykcolor    %        This gets the printer to apply the UCR and BG functions to the rgb value and give us the cmyk we want.
  371.                 
  372.                 % Now stuff the cmyk into the 4 arrays.
  373.                 
  374.                                                                             %    Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i] yellow[i] black[i]
  375.                 5 index 5 index 3 -1 roll            % Stack is:    colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i] yellow[i] newArray i black[i]
  376.                 put                                                        % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i] yellow[i], and we stuffed black in newArray
  377.                 5 index 4 index 3 -1 roll            % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i] blueArray i yellow[i]
  378.                 put                                                        % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i], and we stuffed yellow in blueArray
  379.                 5 index 3 index 3 -1 roll            % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] magenta[i] greenArray i magenta[i]
  380.                 put                                                        % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i], and we stuffed magenta in greenArray
  381.                 5 index 2 index 3 -1 roll         % Stack is: colorSpace N redArray greenArray blueArray newArray i cyan[i] redArray i cyan[i]
  382.                 put                                                        % Stack is: colorSpace N redArray greenArray blueArray newArray i, and we stuffed cyan in redArray
  383.                 pop                                                        % Stack is: colorSpace N redArray greenArray blueArray mewArray
  384.                 
  385.             } for
  386.             
  387.             % redArray greenArray blueArray mewArray has been transformed into cyanArray magentaArray yellowArray blackArray
  388.             
  389.                                                                     % stack is: colorSpace N cyanArray magentaArray yellowArray blackArray
  390.             6 -2 roll                                        % stack is: cyanArray magentaArray yellowArray blackArray colorSpace N
  391.             pop 4                                                % stack is: cyanArray magentaArray yellowArray blackArray colorSpace 4, ready for CreateColorSpace
  392.                     
  393.         } if        
  394.     
  395.     } Bdef
  396.  
  397. {restore} if                                        % De-define the procedure if we are instructed to do wo.
  398.  
  399.  
  400.  
  401. %<FF>
  402. %
  403. %            Procedure:            CreateColorSet
  404. %
  405. %            Procedure creates an colorSet dictionary.
  406. %
  407. %            cmpArray1… cmpArrayN colorSpace N CreateColorSet dict
  408. %
  409. %                cmpArray1 through N:            Array of component values for each component.
  410. %                colorSpace:                                If applicable, a Level-2 ColorSpace, otherwise nil
  411. %                N:                                                Number of components, 1 implies gray, 3 implies rgb, 4 cmyk unless there is a colorspace
  412. %                                                                        in which case it will be assumed that the number of components makes sense for setcolor
  413. %
  414. %                dict:                                            a colorSet dictionary.
  415. %
  416. /CreateColorSet {
  417.  
  418.     currentdict /PortablizeColorSetParams known {PortablizeColorSetParams} if            % If we are portable, make sure colorSet is.
  419.     currentdict /RGBtoCMYKColorSetParams known {RGBtoCMYKColorSetParams} if                % If we are on a CMYK level-1 device, then convert the RGB set to CMYK
  420.  
  421.     5 dict begin                                    % Create a dictionary for the colorset.
  422.  
  423.         exch                                                % Swap the space and N on the stack.
  424.         /ColorSpace Xdef                        % Save the color space in the dictionary.
  425.         1 index length /Size Xdef        % Get the size of the 1st array, it should be the same for all.
  426.         dup /Num Xdef                                % Save number of components in the dictionary
  427.         array                                                % Create an array with one element per component
  428.         astore                                            %    Put the arrays of components into the array.
  429.         /Components Xdef                        % Save this array in the components field of the dictionary.
  430.         
  431.         %
  432.         % Figure out which color operator to use
  433.         %
  434.         ColorSpace null eq {            % If there is no colorspace
  435.                                                             %        use one of the device dependant operators.
  436.             /SetColorOp
  437.  
  438.             Num 1 eq  {                            %        If it is one component
  439.  
  440.                 /setgray load def            %            use setgray
  441.  
  442.             }    {                                            %        else
  443.  
  444.                 Num 3 eq {                        %        If it is 3 components
  445.                     /GXSetRGBColor load def        % Use setrgbcolor
  446.                 } {                                        %        else
  447.                     /setcmykcolor load def        % Use setcmykcolor
  448.                 }    ifelse
  449.                 
  450.             }    ifelse
  451.                 
  452.         } {                                                % else Use the level-2 coloer operator.
  453.         
  454.             /SetColorOp /setcolor load def
  455.         
  456.         } ifelse
  457.     
  458.     currentdict end
  459.  
  460. } Bdef
  461.  
  462. %<FF>
  463. %
  464. %        Procedure:        SetIndexedColor
  465. %
  466. %        Procedure sets the current color to be the color in the indexed color space.
  467. %            Warning:  In level-2, this procedure also sets the current color space to be that of the ColorSet dictionary
  468. %                                 and it is left that way.
  469. %
  470. %        index setDict SetIndexedColor -
  471. %
  472. %        index:            The index of the color. (zero based)
  473. %        setDict:        A valid colorSet dictionary.
  474. %
  475. /SetIndexedColor {
  476.  
  477.     begin
  478.     
  479.         ColorSpace null ne {ColorSpace GXSetCSpace} if            % Set the color space if necessary.
  480.         Components {1 index get exch} forall pop                        % Get the components from the arrays.
  481.         SetColorOp
  482.     
  483.     end
  484.  
  485. } Bdef
  486.  
  487.  
  488.  
  489. %<FF>
  490. %
  491. %
  492. %            Stuff for level-2 indexed colorspace bitmaps:
  493. %
  494. languagelevel 2 ge {
  495.  
  496.     %
  497.     %    Lookup procedure for a level-2 indexed color space.  This is passed in the array to 
  498.     %        setcolorspace:
  499.     %        It expects the index of the color on the stack.
  500.     %
  501.     /LookupProc {
  502.  
  503.         CurrColorSet /Components get {            % For each component:
  504.  
  505.             1 index dup                                                %        Get the color index from the stack.
  506.             CurrColorSet /Size get ge     {            %        If the passed index is too big:
  507.                 pop pop 0                                                %            pop off the parameters and put 0 for the component.
  508.             } {                                                                %        Else
  509.                 get                                                            %            Get the component value from the array.
  510.             }    ifelse
  511.             exch                                                            %     Get component array back on top of stack.
  512.  
  513.         } forall 
  514.         
  515.         pop                                                                        % Get rid of duplicate component array
  516.  
  517.     } Bdef
  518.  
  519. } if
  520.  
  521.  
  522. %<FF>
  523. %
  524. %    Procedure to draw level-2 indexed color space bitmap.
  525. %
  526. languagelevel 2 ge {
  527.  
  528.     %
  529.     %  Procedure DoIndexedBitmap:
  530.     %        Procedure renders a bitmap shape using the current colorset.  Level-2 only.
  531.     %
  532.     %        width height bits/sample x y hex rowBytes DoIndexedBitmap -
  533.     %                    width:                    The width in pixels of the bitmap.
  534.     %                    height:                    The height in pixels of the bitmap.
  535.     %                    bits/sample:        pixelSize value.
  536.     %                    x, y:                        Position of the bitmap in user space.
  537.     %                    hex:                        Boolean, true if data will be hex.  (ignored when data is in string array)
  538.     %                    rowBytes:                #bytes required for one scanline.  (If 0, data is assumed to be in string array)
  539.     %
  540.     /DoIndexedBitmap { save
  541.  
  542.         8 1 roll                                        % Move save-level behind parameters on stack.
  543.         
  544.         dup 0 gt {
  545.  
  546.             /pixString exch string store                % allocate a string for the scanline.
  547.             
  548.             /RstrRead exch                                            % Define read operation based on hex value.
  549.                 {/readhexstring}
  550.                 {/readstring}        
  551.             ifelse
  552.             load def
  553.             
  554.         } {
  555.         
  556.             pop pop                                                        % Get rid of duplicate rowBytes and hex string.        
  557.             /pixString null store                            % null pixString is flag for get data out of string array.
  558.         
  559.         } ifelse
  560.  
  561.         1 0 0 1
  562.         6 -2 roll neg exch neg exch                    % Make mapping [1 0 0 1 -x -y]
  563.         ScratchMatrix astore                                % for image dictionary to position bitmap correctly.
  564.         
  565.         % stack is now width height bits/sample matrix
  566.         
  567.         %
  568.         %    Define the indexed color space, old one will be restored by restore at end of this execution.
  569.         %
  570.         %        Creating the array [ /Indexed base hival lookup ]
  571.         [
  572.             /Indexed
  573.             
  574.             CurrColorSet begin                        % Put the color set dictionary on the stack.
  575.             
  576.                 ColorSpace null eq {                % If the color space is null, use a device space based on Num
  577.                 
  578.                     Num 1 eq                                     %        1 is DeviceGray
  579.                         {/DeviceGray}
  580.                         { Num 3 eq
  581.                                 {/DeviceRGB}                %        3 is DeviceRGB
  582.                                 {/DeviceCMYK}                %        4 is DeviceCMYK
  583.                             ifelse
  584.                         }    ifelse
  585.  
  586.                 } {                                                    % Else put the color space array on the stack.
  587.                     ColorSpace /CSA get
  588.                 } ifelse
  589.                                                                         % Stack now has base color space                        (base)
  590.     
  591.                 Size                                                % Put the number of entries on the stack.   (hival)
  592.                 
  593.             end
  594.             
  595.             /LookupProc load                            % Put the lookup procedure on the stack.    (lookup)
  596.  
  597.         ] setcolorspace
  598.         
  599.         % Set the color rendering dictionary, if the color space isn't null.
  600.         
  601.         CurrColorSet /ColorSpace get dup null ne {GXSetCRD} {pop} ifelse
  602.         
  603.         %
  604.         %  Create a dictionary for the image operator.
  605.         %
  606.         7 dict dup begin
  607.         
  608.             % stack is now: width height bits/sample matrix dict
  609.             
  610.             5 1 roll
  611.             /ImageMatrix Xdef
  612.             /BitsPerComponent Xdef
  613.             /Height Xdef
  614.             /Width Xdef
  615.             
  616.             /ImageType 1 def
  617.             /Decode [0 2 BitsPerComponent exp 1 sub] def
  618.  
  619.             pixString null ne {
  620.             
  621.                 /DataSource /ReadRaster load def
  622.                 
  623.             } {
  624.             
  625.                 /DataSource /StringDataIn load def
  626.                 BitmapStrings 0                                            % Put string array on stack and first index
  627.                 3 2 roll                                                        % Move them behind image dictionary.
  628.             
  629.             } ifelse
  630.         
  631.         end
  632.         
  633.         image                % Execute the image operator.
  634.  
  635.         % pop off array and last array index if we were reading from string.        
  636.         pixString null eq {pop pop} if
  637.  
  638.     restore } Bdef
  639.     
  640.  
  641. } if
  642.  
  643.  
  644. %<FF>
  645. %
  646. %            Indexed color set bitmap stuff for level-1.  Uses transfer functions to simulate effect.
  647. %
  648. languagelevel 1 eq {
  649.  
  650.     /MaxSampleInt 0 store                        % 2^pixelsize - 1 for current image operation.
  651.  
  652.     %
  653.     %    LookupComponent:            For a given input value, looks up the component value in the colorset.
  654.     %
  655.     %        input component-index LookupComponent output
  656.     %
  657.     %            input:                        Input component value from 0-1.
  658.     %            comp-index:                Index of color component to get.
  659.     %
  660.     %            output:                        Output value for component from 0-1.
  661.     %
  662.     /LookupComponent {
  663.  
  664.         CurrColorSet /Components get                % Get array of components
  665.         exch get                                                        % Get the correct component array
  666.         exch MaxSampleInt mul round cvi            % Get index into the array.
  667.         dup
  668.         CurrColorSet /Size get ge {                    % Get it if it is in the array, else return zero.
  669.             pop pop 0
  670.         } {
  671.             get
  672.         } ifelse
  673.  
  674.     } Bdef
  675.  
  676.  
  677.     %
  678.     %  Procedure DoIndexedBitmap:
  679.     %        Procedure renders a bitmap shape using the colorset.  Level-1 version.
  680.     %        This is done by installing transfer functions which use the input value
  681.     %        to index the color set arrays.
  682.     %
  683.     %        width height bits/sample x y hex rowBytes DoIndexedBitmap -
  684.     %                    width:                    The width in pixels of the bitmap.
  685.     %            `        height:                    The height in pixels of the bitmap.
  686.     %                    bits/sample:        pixelSize value.
  687.     %                    x, y:                        Position of the bitmap in user space.
  688.     %                    hex:                        Boolean, true if data will be hex.  (Ignored when data is in string array)
  689.     %                    rowBytes:                #bytes required for one scanline.    (If 0, data is assumed to be in string array)
  690.     %
  691.     /DoIndexedBitmap { save
  692.  
  693.         8 1 roll                                        % Move save-level behind parameters on stack.
  694.  
  695.         dup 0 gt {                            % If data is not in string array:
  696.         
  697.             /pixString exch string store                    % allocate a string for the scanline.
  698.             
  699.             /RstrRead exch                                            % Define read operation based on hex value.
  700.                 {/readhexstring}
  701.                 {/readstring}        
  702.             ifelse
  703.             load def
  704.  
  705.             2 index 2 exch exp 1 sub /MaxSampleInt exch store            % Save the maximum sample integer value.
  706.             
  707.             InstallColorSetTransfers                        % Do this here, handled by PatternFill and DashStroke for string case.
  708.             
  709.         } {                    % Else data is in string array.
  710.         
  711.             pop pop                                                % get rid of duplicate rowbytes and hex string.
  712.             /pixString null store                    % null pixString is flag for get data out of string array.
  713.         
  714.         } ifelse
  715.  
  716.         1 0 0 1
  717.         6 -2 roll neg exch neg exch                    % Make mapping [1 0 0 1 -x -y]
  718.         ScratchMatrix astore                                % for image dictionary to position bitmap correctly.
  719.         
  720.         % stack is now width height bits/sample matrix
  721.  
  722.         CurrColorSet /Num get dup 1 eq {                    % 1 component is gray-scale printer.
  723.         
  724.             pop                    % Get rid of duplicate of Num
  725.         
  726.             pixString null ne {
  727.             
  728.                 /ReadRaster load 
  729.                 
  730.             } {
  731.             
  732.                 /StringDataIn load
  733.                 BitmapStrings 0 7 2 roll
  734.             
  735.             } ifelse
  736.             
  737.             image
  738.         
  739.         } {         % Else is color device, determine rgb or cmyk
  740.                     
  741.             3 eq {            % RGB
  742.                 
  743.                 %
  744.                 %  data-source procedures.  First one reads data and duplicates it twice to get other two components
  745.                 %    Other two data sources do nothing.  This makes it so each transfer function gets
  746.                 %         the same index.
  747.                 %
  748.                 pixString null ne {
  749.                 
  750.                     {ReadRaster dup dup} {} {} 
  751.                     
  752.                 } {
  753.                 
  754.                     {StringDataIn dup dup} {} {} BitmapStrings 0 9 2 roll
  755.                 
  756.                 } ifelse
  757.                 
  758.                 true 3 GXColorImage
  759.             
  760.             } {                    % CMYK            
  761.             
  762.                 % First data source procedure reads the data and duplicates it 3 times.  See above comment.
  763.                 %        for rgb case.
  764.                 pixString null ne {
  765.                 
  766.                     {ReadRaster dup dup dup } {} {} {}
  767.                     
  768.                 } {
  769.                 
  770.                     {StringDataIn dup dup dup} {} {} {} BitmapStrings 0 10 2 roll
  771.                 
  772.                 } ifelse
  773.                 
  774.                 true 4 GXColorImage
  775.                 
  776.             } ifelse
  777.         
  778.         } ifelse
  779.         
  780.         pixString null eq {pop pop} if         % if data was in array, pop off array and index.
  781.                 
  782.     restore } Bdef
  783.  
  784. } if
  785.  
  786. %<FF>
  787. %
  788. %        Procedure to install transfer functions using that map into the current color set.
  789. %
  790. languagelevel 1 eq {
  791.  
  792.     /InstallColorSetTransfers {
  793.     
  794.         CurrColorSet /Num get dup 1 eq {                    % 1 component is gray-scale printer.
  795.         
  796.             /OldGrayTransfer currenttransfer store
  797.             
  798.             {0 LookupComponent OldGrayTransfer} settransfer
  799.             
  800.             pop                    % Get rid of duplicate of Num
  801.             
  802.         } {         % Else is color device, determine rgb or cmyk
  803.                     
  804.             3 eq {            % RGB
  805.                 
  806.                 currentcolortransfer
  807.             
  808.                 /OldGrayTransfer exch store
  809.                 /OldBlueTransfer exch store
  810.                 /OldGreenTransfer exch store
  811.                 /OldRedTransfer exch store
  812.                 
  813.                 {0 LookupComponent OldRedTransfer}
  814.                 {1 LookupComponent OldGreenTransfer}
  815.                 {2 LookupComponent OldBlueTransfer}
  816.                 {OldGrayTransfer}
  817.                 setcolortransfer
  818.                         
  819.             } {                    % CMYK
  820.             
  821.                 currentcolortransfer
  822.     
  823.                 /OldBlackTransfer exch store
  824.                 /OldYellowTransfer exch store
  825.                 /OldMagentaTransfer exch store
  826.                 /OldCyanTransfer exch store
  827.                 
  828.                 %
  829.                 % The values must first be inverted becuase PostScript always treats transfer functions
  830.                 % in additive space.  So, invert values before lookup, then invert result.
  831.                 %
  832.                 {1 exch sub 0 LookupComponent 1 exch sub OldCyanTransfer}
  833.                 {1 exch sub 1 LookupComponent 1 exch sub OldMagentaTransfer}
  834.                 {1 exch sub 2 LookupComponent 1 exch sub OldYellowTransfer}
  835.                 {1 exch sub 3 LookupComponent 1 exch sub OldBlackTransfer}
  836.                 setcolortransfer
  837.             
  838.             } ifelse
  839.             
  840.         } ifelse
  841.         
  842.     } Bdef
  843.         
  844. } if
  845.  
  846.  
  847. %<FF>
  848. % Procedure calls DrawIndexedBitmap to use string array rather than current file.
  849. %
  850. %        width height bits/sample x y DrawIndexedBitmapStrings -
  851. %
  852. /DrawIndexedBitmapStrings {
  853.  
  854.     F 0 DoIndexedBitmap                        % Pass 0 for rowbytes, flags DoIndexedBitmap to use strings.
  855.  
  856. } Bdef
  857.  
  858.  
  859.  
  860.  
  861.  
  862. %<FF>
  863. %                Procedure Do1bitBitmap
  864. %
  865. %                width height x y hex rowBytes Do1bitBitmap -
  866. %
  867. %                    width:                    The width in pixels of the bitmap.
  868. %            `        height:                    The height in pixels of the bitmap.
  869. %                    x, y:                        Position of the bitmap in user space.
  870. %                    hex:                        Boolean, true if data will be hex.
  871. %                    rowBytes:                #bytes required for one scanline.
  872. %
  873. %
  874. %
  875. /Do1bitBitmap {
  876.  
  877.     dup type /arraytype eq                % If there is a matrix on top, that means bitmap is really rasterized shape, use imagemask.
  878.     CurrOrMode 0 ne or     {            % or For or-mode, we can use the image mask.
  879.     
  880.         DoImageMask
  881.  
  882.     } {                                        % Invoke the indexed bitmap procedure
  883.     
  884.         1                    % Put a 1 on the stack for bits/sample
  885.                             % stack is now: width height x y hex rowBytes bits/sample
  886.         5 1 roll    % Stack is now: width height bits/sample x y hex rowBytes
  887.         
  888.         DoIndexedBitmap
  889.     
  890.     } ifelse
  891.  
  892. } Bdef
  893.  
  894.  
  895.  
  896.  
  897. %<FF>
  898. % This function is called from within the definition of an image dictionary. (image dictionary must be on top of dict stack)
  899. %        This function sets up the decode entry in the image dictionary based upon the range in the current color space array.
  900. %
  901. /SetImageDecodeEntry {
  902.     %
  903.     % cause pixel values to expand to color space range.
  904.     %            
  905.     /Decode [0 1.0 0 1.0 0 1.0] def                                                % Initialize it to be 0-1 for all components.
  906.     currentcolorspace 0 get /CIEBasedABC eq {                            % But, if the current color space is a CIEBasedABC.
  907.         currentcolorspace 1 get dup /RangeABC known {                %   And it has a RangeABC entry
  908.             /RangeABC get /Decode exch def                                        %   use that as the decoding for the bitmap data.
  909.         } {                                                                                                    % else
  910.             pop                                                                                                %        Get rid of extra copy of color space dictionary.
  911.         } ifelse                                                                                        % endif
  912.     } if
  913.     
  914. } bind def
  915.  
  916.  
  917. %
  918. %
  919. %            Level 2 device independant color space bitmap procedures.  (One for strings, one for for file input)
  920. %            Routines set up a dictionary for the Image Operator to use the current color space
  921. %
  922. languagelevel 2 ge {
  923.  
  924.     %
  925.     %        Procedure:    DoLevel2ColorImage
  926.     %            Procedure draws a color image in the current level-2 color space for device independent colors
  927.     %
  928.     %        width height bits/sample x y hex DoLevel2ColorImage -
  929.     %                    width:                    The width in pixels of the bitmap.
  930.     %                    height:                    The height in pixels of the bitmap.
  931.     %                    bits/sample:        pixelSize value.
  932.     %                    x, y:                        Position of the bitmap in user space.
  933.     %                    hex:                        Boolean, true if data will be hex.
  934.     %
  935.     /DoLevel2ColorImage {
  936.     
  937.         9 dict begin
  938.             
  939.             /ImageType 1 def
  940.             
  941.             % hex flag is on top of stack, define DataSource based upon value.
  942.             {
  943.                 /DataSource currentfile /ASCIIHexDecode filter def
  944.             } {
  945.                 /DataSource currentfile def
  946.             } ifelse
  947.             
  948.             % Stack has x,y on top:, make matrix [1 0 0 1 -x -y] for ImageMatrix
  949.             
  950.             neg exch neg exch matrix translate /ImageMatrix Xdef
  951.             
  952.             /BitsPerComponent Xdef
  953.     
  954.             /Height Xdef
  955.             /Width Xdef
  956.             
  957.             SetImageDecodeEntry            % Setup the /Decode entry in the image dictionary.
  958.                 
  959.             currentdict            % Leave the image dictionary on the stack.
  960.             
  961.         end
  962.         
  963.         image                            % Execute the image operator on the dictionary.
  964.                     
  965.     } Bdef
  966.     
  967.     
  968.     %<FF>
  969.     %
  970.     %        Procedure:    DoLevel2ColorImageString
  971.     %            Procedure draws a color image in the current level-2 color space for device independent colors
  972.     %            Using the strings as input rather than the current file.
  973.     %            The shape dictionary with the entry "BitmapStrings" will be assumed to be on the dictionary stack.
  974.     %
  975.     %        width height bits/sample x y DoLevel2ColorImageString -
  976.     %                    width:                    The width in pixels of the bitmap.
  977.     %                    height:                    The height in pixels of the bitmap.
  978.     %                    bits/sample:        pixelSize value.
  979.     %                    x, y:                        Position of the bitmap in user space.
  980.     %
  981.     /DoLevel2ColorImageString {
  982.     
  983.         9 dict begin
  984.             
  985.             /ImageType 1 def
  986.     
  987.             /DataSource /StringDataIn load def    
  988.             
  989.             % Stack has x,y on top:, make matrix [1 0 0 1 -x -y] for ImageMatrix
  990.             
  991.             neg exch neg exch matrix translate /ImageMatrix Xdef
  992.             
  993.             /BitsPerComponent Xdef
  994.     
  995.             /Height Xdef
  996.             /Width Xdef
  997.             
  998.             SetImageDecodeEntry            % Setup the /Decode entry in the image dictionary.
  999.             
  1000.             BitmapStrings 0    % Put the string array and the initial index on the stack.
  1001.             
  1002.             currentdict            % Leave the image dictionary on the stack.
  1003.             
  1004.         end
  1005.         
  1006.         image                            % Execute the image operator on the dictionary.
  1007.                     
  1008.         pop pop                        % Get rid of last index and copy of string array.    
  1009.  
  1010.     } Bdef
  1011.     
  1012. } if                % language level >= 2
  1013.